package Agents;

import jade.core.AID;
import jade.core.behaviours.CyclicBehaviour;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;
import AOP.Printer;
import Behavior.EmitBehavior;
import Messages.AMessage;
import Messages.AMessage.MessageType;
import Messages.AMessage.Units;
import Messages.MeasureMessage;
import Messages.NotUnderstoodMessage;
import Messages.OfficeRegionMessages.AdjustToUser;

@SuppressWarnings({ "serial", "unused" })
public class FloorHeater extends AActuator
{
	protected void setup() 
	{
		DFAgentDescription dfd = new DFAgentDescription();
		ServiceDescription sd = new ServiceDescription();   
		sd.setType(AMessage.GlobalNames.FLOOR_HEATER_AGENT.get()); 
		sd.setName(getName());
		sd.setOwnership("FloorHeater");
		dfd.setName(getAID());
		dfd.addServices(sd);
		try { DFService.register(this,dfd); }
		catch (FIPAException e)
		{
			System.err.println(getLocalName() + " registration with DF unsucceeded. Reason:  " + e.getMessage());
		}
		
		this.unit = AMessage.Units.TEMPERATURE;
		this.value = 3;
		this.setpoint = 60;
		this.currentpoint = 60;
		addBehaviour(new HandleFloorHeaterMessagesBehaviour());
		addBehaviour(new EmitBehavior(this, AMessage.unitsManipulatingConstant*2));
	}
	
	public void calculateNewValue()
	{
		//System.out.println("HEATING: "+((setpoint-currentpoint)*0.1)); //TODO "HEATING: "
		value = (int) ((setpoint-currentpoint)*0.1);
		if(value >10)
			value = 10;
		else if(value < 0)
			value = 0;
	}
	
	private class HandleFloorHeaterMessagesBehaviour extends CyclicBehaviour
	{
		public void action() 
		{
			ACLMessage  msg = myAgent.receive();
			ACLMessage reply;
			
			if(msg != null)
			{
				String content = msg.getContent();
				reply = msg.createReply();
				boolean doReply = false;
				
				AMessage message = null;
				try
				{
					message = AMessage.retrieveMessage(content);
				}
				catch(Exception e)
				{
					Printer.error(msg);
				}
				switch(AMessage.GlobalNames.decode(message.getSender()))
				{
					case OFFICE_REGION_AGENT:
						if(msg.getPerformative() == ACLMessage.REQUEST)
						{
							switch(message.getMessageType())
							{
								case ADJUST:
									if(((AdjustToUser)message).unit == Units.TEMPERATURE)
									{
										setpoint = ((AdjustToUser)message).value;
										//System.out.println("=============== new Setpoint: " + setpoint); //TODO
										Printer.Print(myAgent.getLocalName(), value, setpoint, currentpoint);
										
									}
									break;
								default:
									reply.setPerformative(ACLMessage.NOT_UNDERSTOOD);
									//System.out.println("Unexpected-act " + ACLMessage.getPerformative(msg.getPerformative())); //TODO
									reply.setContent(NotUnderstoodMessage.constructSpecialMessage((Messageable)myAgent, message));
									reply.addReceiver(msg.getSender());
									doReply = true;
									break;
							}
						}
						break;
					case TEMPERATURE_SENSOR_AGENT:
						if(msg.getPerformative() == ACLMessage.INFORM)
						{
							switch(message.getMessageType())
							{
								case MEASUREMENT:
									currentpoint = ((MeasureMessage)message).value;
									Printer.Print(myAgent.getLocalName(), value, setpoint, currentpoint);
									//System.out.println("=#=#=#=# " + mm.value);//TODO
									break;
								default:
									reply.setPerformative(ACLMessage.NOT_UNDERSTOOD);
									//System.out.println("Unexpected-act " + ACLMessage.getPerformative(msg.getPerformative())); //TODO
									reply.setContent(NotUnderstoodMessage.constructSpecialMessage((Messageable)myAgent, message));
									//reply.addReceiver(msg.getSender());
									doReply = true;
									break;
							}
						}
						break;
					default:
						break;
				}
				if(doReply)
				{
					myAgent.send(reply);
				}
			}
		}
		
	}
}
